package y.q.h.util;

import lombok.Data;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

import static cn.hutool.core.text.CharSequenceUtil.toUnderlineCase;

/**
 * Map转换为实体类
 *
 * @author SongRenShuo
 * @date 2023/08/21
 */
public class MapToEntityUtil {

    /**
     * 测试Map转实体
     */
    public static void main(String[] args) throws Exception {

        // 创建Map对象
        Map<String, Object> map = new HashMap<>();
        map.put("id", "1");
        map.put("user_name", "zhangSan");
        map.put("pass_word", "123456");
        // 创建实体类Class对象
//        Class<?> clazz = Class.forName("com.song.entity.Users");
        // 将Map转换为实体类对象
//        mapToEntity(map, Users.class);

        mapToEntity(map, Users.class, true);
    }

    /**
     * 将Map转换为实体类
     *
     * @param map   要转换的Map对象 *
     * @param clazz 实体类Class对象
     * @return 转换后的实体类对象
     */
    public static Object mapToEntity(Map<String, Object> map, Class<?> clazz) throws Exception {

        return mapToEntity(map, clazz, false);
    }


    /**
     * 将Map转换为实体类
     *
     * @param map    要转换的Map对象 *
     * @param clazz  实体类Class对象
     * @param isHump 是否转换为驼峰 helloWorld -> hello_world
     * @return 转换后的实体类对象
     */
    public static Object mapToEntity(Map<String, Object> map, Class<?> clazz, Boolean isHump) throws Exception {
        // 创建实体类对象
        Object entity = clazz.getDeclaredConstructor().newInstance();
        // 获取实体类的所有属性
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            // 设置属性可访问
            field.setAccessible(true);
            // 获取属性名
            String fieldName = field.getName();
            if (isHump) {
                fieldName = toUnderlineCase(field.getName());
            }
            // 如果Map中包含该属性名
            if (map.containsKey(fieldName)) {
                // 获取属性对应的值
                Object fieldValue = map.get(fieldName);
                // 获取属性的数据类型
                Class<?> fieldType = field.getType();
                // 判断属性是否为int类型且属性值为字符串
                if (fieldType == Integer.class && fieldValue instanceof String) {
                    // 将属性值转换为字符串
                    String fieldValueString = (String) fieldValue;
                    if ("".equals(fieldValueString)) {
                        // 如果属性值为空字符串，则跳过设置属性值的步骤
                        continue;
                    }
                    // 将字符串属性值转换为int类型
                    fieldValue = Integer.parseInt(fieldValueString);
                }
                // 处理其他类型的字段判断和转换...
                // 设置实体类对象的属性值
                field.set(entity, fieldValue);
            }
        }
        // 输出转换前和转换后的Map和实体类对象
        System.out.println("转换前(Map): " + map);
        System.out.println("转换后(实体): " + entity);
        // 输出Map和实体类对象的类型
//        System.out.println("转换前数据类型: " + map.getClass().getName());
//        System.out.println("转换后数据类型: " + entity.getClass().getName());
        return entity;
    }


    @Data
    static
    class Users {
        /**
         * 主键
         */
        private Integer id;
        /**
         * 姓名
         */
        private String userName;
        /**
         * 密码
         */
        private String passWord;
    }
}
